﻿using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.IO.IsolatedStorage;
using System.Linq;
using System.Net;
using System.Web;
using System.Runtime.Serialization;
using System.Xml.Serialization;
using System.Xml;


namespace Leffaetsin.Services
{
    [DataContract]
    public class ImdbMovie
    {
        [DataMember]
        public string Title { get; set; }
        [DataMember]
        public string Rating { get; set; }
        [DataMember]
        public string Year { get; set; }

        // TODO PANU: lisää expire!!
    }

    // TODO: periytä List<ImdbMovie>:sta??
    [DataContract]
    public class ImdbMovies
    {
        [DataMember]
        public List<ImdbMovie> Movies { get; set; }
    }

    public class IsolatedStorageService
    {
        private ImdbMovies movies = null;

        public IsolatedStorageService(bool forceRefresh = false)
        {
            if (forceRefresh || !HasMovieData())
                DownloadMovieData();

            movies = GetMovieDataFromStore();
        }

        public IsolatedStorageFile GetStore()
        {
            return IsolatedStorageFile.GetMachineStoreForDomain();
        }

        public bool HasMovieData(string fileName = "imdb-movies.txt")
        {
            var fileNames = GetStore().GetFileNames(fileName).ToList();

            return fileNames.Any(f => f == fileName);
        }



        public void DownloadMovieData(string fileName = "imdb-movies.txt")
        {
            WebClient Client = new WebClient();


            var data = Client.DownloadData("ftp://ftp.funet.fi/pub/mirrors/ftp.imdb.com/pub/ratings.list.gz");
            var stream = new MemoryStream(data);

            var allMovies = new ImdbMovies();
            allMovies.Movies = new List<ImdbMovie>();

            using (GZipStream zipStream = new GZipStream(stream, CompressionMode.Decompress))
            {
                using (var sr = new StreamReader(zipStream, System.Text.Encoding.Default))
                {

                    var row = sr.ReadLine();
                    while (row != null)
                    {
                        row = sr.ReadLine();
                        if (row == null)
                            continue;

                        if (row.Length < 28)
                            continue;

                        row = row.Substring(27).Replace("\"", "");

                        var leffa = row.Split(new string[] { "  " }, StringSplitOptions.None);
                        if (leffa.Length != 2)
                            continue;

                        var rating = row[0];
                        var leffa2 = leffa[1].Split(new string[] { " (" }, StringSplitOptions.None);
                        if (leffa2.Length != 2)
                            continue;

                        var imdbMovie = new ImdbMovie();
                        imdbMovie.Title = leffa2[0].Trim();
                        imdbMovie.Year = leffa2[1].Substring(0, 4);
                        imdbMovie.Rating = leffa[0];

                        allMovies.Movies.Add(imdbMovie);
                    }
                }
            }

            XmlSerializer xsSubmit = new XmlSerializer(typeof(ImdbMovies));

            StringWriter sww = new StringWriter();
            XmlWriter writer = XmlWriter.Create(sww);
            xsSubmit.Serialize(writer, allMovies);
            WriteToStore(sww.ToString());
        }

        private void WriteToStore(string text, string fileName = "imdb-movies.txt")
        {
            IsolatedStorageFileStream oStream = new IsolatedStorageFileStream(fileName, FileMode.Create, GetStore());

            StreamWriter writer = new StreamWriter(oStream);
            writer.Write(text);
            writer.Close();
        }



        public string GetRatingFromStore(string movieName, string movieYear, string fileName = "imdb-movies.txt")
        {
            var movie = movies.Movies.FirstOrDefault(e => e.Title.Equals(movieName, StringComparison.InvariantCultureIgnoreCase) && e.Year == movieYear);
            if (movie == null)
                movie = movies.Movies.FirstOrDefault(e => e.Title.Equals(movieName, StringComparison.InvariantCultureIgnoreCase));

            if (movie == null)
                return "";
            else
                return movie.Rating;
        }

        private ImdbMovies GetMovieDataFromStore(string fileName = "imdb-movies.txt")
        {
            IsolatedStorageFileStream iStream = new IsolatedStorageFileStream(fileName, FileMode.Open, GetStore());

            StreamReader reader = new StreamReader(iStream);
            String line;

            XmlSerializer x = new XmlSerializer(typeof(ImdbMovies));
            ImdbMovies imdbMovies = (ImdbMovies)x.Deserialize(reader);
            reader.Close();
            return imdbMovies;
        }
    }
}